package com.maxd.modules.coupon.controller;

import com.gexin.fastjson.JSON;
import com.maxd.adapter.IgnoreSecurity;
import com.maxd.error.Result;
import com.maxd.error.ResultUtil;
import com.maxd.model.ExcelData;
import com.maxd.model.PublisherOrderDtoBean;
import com.maxd.model.UserInfo;
import com.maxd.modules.coupon.entity.CouponAmount;
import com.maxd.modules.coupon.entity.CouponCard;
import com.maxd.modules.coupon.entity.GenerateCouponCard;
import com.maxd.modules.coupon.mapper.CouponAmountMapper;
import com.maxd.modules.coupon.service.CouponAmountService;
import com.maxd.modules.coupon.service.CouponCardService;
import com.maxd.modules.coupon.utils.CouponCardUtil;
import com.maxd.modules.syslog.entity.RequestLogs;
import com.maxd.modules.syslog.service.RequestLogsService;
import com.maxd.service.userinfo.IUserService;
import com.maxd.utils.ExportExcelUtils;
import com.mysql.cj.jdbc.util.ResultSetUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Auther: Laban:yubo_010@163.com
 * @Date: 2020/11/12 15:47
 * @Description:
 */
@RestController
@Api(value="优惠卡券管理",tags={"优惠卡券管理"})
@RequestMapping(value = "/couponCard")
public class CouponCardController {

    private final static Logger log = LoggerFactory.getLogger(CouponCardController.class);

    @Autowired
    private CouponCardService couponCardService;

    @Autowired
    private CouponAmountService couponAmountService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private RequestLogsService requestLogsService;

    CouponCardUtil couponCardUtil = new CouponCardUtil();

    /**
     * 分页查询优惠卡列表
     * @param page
     * @param size
     * @return 返回是分 需要前端去转元
     */
    @RequestMapping(value = "/findAllCouponCard", method = RequestMethod.POST)
    @ApiOperation("查询优惠卡券列表")
    //@IgnoreSecurity
    public Result findAllCouponCard(@RequestBody CouponCard couponCard, @RequestParam Integer page, @RequestParam int size) {
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "findAllCouponCard",null,
                "/couponCard/findAllCouponCard", JSON.toJSONString(couponCard));
        requestLogsService.saveRequestLogs(requestLogs);

        CouponCard couponCard1 = couponCardUtil.copyNull(couponCard);
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size,Sort.by(order));
        return couponCardService.findAll(couponCard1,pageable);
        //todo 最好写构造器 之后直接构造器查询
    }


    /**
     * 系统生成优惠卡
     */
    @RequestMapping(value = "/generateCouponCard", method = RequestMethod.POST)
    @ApiOperation("系统生成优惠卡")
    //@IgnoreSecurity
    public Result generateCouponCard(@RequestBody GenerateCouponCard generateCouponCard) {
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "generateCouponCard",null,
                "/couponCard/generateCouponCard", JSON.toJSONString(generateCouponCard));
        requestLogsService.saveRequestLogs(requestLogs);

        //参数校验
        Result result = couponCardUtil.verificationParameter(generateCouponCard);
        if (result!=null){
            return result;
        }

        //随机生成卡片
        List<CouponCard> couponCards = couponCardUtil.randomGenerateCouponCard(generateCouponCard);
        //非空校验
        boolean empty = CollectionUtils.isEmpty(couponCards);
        if(empty==true){
            return ResultUtil.error(606,"系统错误,请稍后再试或联系管理员");
        }

        try {
            couponCards.forEach(couponCard -> {
                couponCardService.save(couponCard);
            });
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.error(606,"系统错误,请稍后再试或联系管理员");
        }

        return ResultUtil.success("卡券生成成功");
    }


    /**
     * 卡券兑换 获取user id
     */
    @RequestMapping(value = "/exchangeCouponCard", method = RequestMethod.POST)
    @ApiOperation("兑换卡券")
    //@IgnoreSecurity
    public Result exchangeCouponCard(@RequestParam String userId,@RequestParam String cardId) {
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "exchangeCouponCard",null,
                "/couponCard/exchangeCouponCard", "userId:"+userId+",cardId:"+cardId);
        requestLogsService.saveRequestLogs(requestLogs);

        //查询卡券是否存
        CouponCard couponCard = couponCardService.getCouponCardByCardId(cardId);
        if(couponCard==null){
            return ResultUtil.error(701,"兑换失败");
        }
        //卡券是否被使用
        if("1".equals(couponCard.getCardIsActivation())){
            return ResultUtil.error(702,"卡券已被使用");
        }

        //检测是否有该用户
        UserInfo userByUserId = iUserService.getUserByUserId(userId);
        if(userByUserId==null){
            return ResultUtil.error(703,"该用户不存在");
        }

        CouponAmount couponAmount = new CouponAmount();
        //检测用户卡券表是否存在
        CouponAmount couponAmountByUserId = couponAmountService.getCouponAmountByUserId(userId);
        if(couponAmountByUserId==null){
            //不存在新建
            CouponAmount saveCouponAmount = couponAmount.saveCouponAmount(new Date(), userId,
                    couponCard.getCardMoney(), "0", "0");
            synchronized (this){
                couponAmountService.addCouponAmount(saveCouponAmount);
            }
        }else{
            //存在即增加抵扣额
            BigDecimal bigDecimalOld = new BigDecimal(couponAmountByUserId.getUserDeductQuota());
            BigDecimal bigDecimalNew = new BigDecimal(couponCard.getCardMoney());
            BigDecimal addAll = bigDecimalOld.add(bigDecimalNew);
            CouponAmount saveCouponAmount = couponAmount.saveCouponAmount(couponAmountByUserId.getCreateTime(),
                    couponAmountByUserId.getUserId(), addAll.toString(),
                    couponAmountByUserId.getUserFrozenAmount(), couponAmountByUserId.getUserProvinceAmount());
            synchronized (this){
                couponAmountService.updateCouponAmountByUserId(saveCouponAmount);
            }
        }

        try {
            //修改卡券状态为 已被使用  将卡券金额增加到用户卡券表
            synchronized (this){
                couponCardService.updateCouponCardByCardId(new Date(),cardId,userId);
            }

        }catch (Exception e){
            return ResultUtil.error(703,cardId+"卡券兑换异常,请稍后再试或联系管理员");
        }

        return ResultUtil.success("兑换成功");
    }


    /**
     * 卡券导出
     * 根据类型和名称导出 根据是否被使用导出
     */
    @RequestMapping(value = "/exportCouponCards", method = RequestMethod.POST)
    @ApiOperation("导出系统卡券")
    //@IgnoreSecurity
    public void exportCouponCards(@RequestBody CouponCard couponCardFrom, HttpServletResponse response) throws Exception {
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "exportCouponCards",null,
                "/couponCard/exportCouponCards", String.valueOf(couponCardFrom));

        CouponCard couponCard1 = couponCardUtil.copyNull(couponCardFrom);
        List<CouponCard> couponCards = couponCardService.findAllNoPage(couponCard1);
        ExcelData data = new ExcelData();
        data.setName("卡券列表");
        List<String> titles = new ArrayList();
        titles.add("卡券名称");
        titles.add("卡券卡号");
        titles.add("卡券金额(单位:分)");
        titles.add("卡券类型(1:用户 2:商户)");
        titles.add("是否被激活/兑换/使用(0:未使用 1:已使用");
        titles.add("卡券所属用户id");
        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList();
        if(couponCards!=null && couponCards.size()>0){
            couponCards.forEach(couponCard -> {
                List<Object> row = new ArrayList();
                row.add(couponCard.getCardName());//卡券名称
                row.add(couponCard.getCardNo());//卡券卡号
                row.add(couponCard.getCardMoney());//卡券金额 单位:分
                row.add(couponCard.getCardType());//卡券类型
                row.add(couponCard.getCardIsActivation());//是否被激活/兑换/使用(0:未使用 1:已使用
                row.add(couponCard.getCardUserId());//卡券所属用户id
                rows.add(row);
            });
        }
        data.setRows(rows);
        ExportExcelUtils.exportExcel(response,"卡券列表.xlsx",data);
    }


    /**
     * 查询某个用户所有的卡券
     */
    @RequestMapping(value = "/findCouponCardListByUserId", method = RequestMethod.POST)
    @ApiOperation("查询某个用户所有的卡券")
    public Result findCouponCardListByUserId(@RequestParam String userId){
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "findCouponCardListByUserId",null,
                "/couponCard/findCouponCardListByUserId", String.valueOf(userId));

        if(userId==null){
            return ResultUtil.error(704,"获取失败,请稍后再试");
        }
        List<CouponCard> allByUserId = couponCardService.findAllByUserId(userId);
        return ResultUtil.success(allByUserId);
    }


    /**
     * 删除多个卡券
     */
    @RequestMapping(value = "/deleteByIdList", method = RequestMethod.POST)
    @ApiOperation("删除多个卡券")
    public Result deleteByIdList(@RequestParam String ids) {
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "deleteByIdList",null,
                "/couponCard/deleteByIdList", String.valueOf(ids));

        couponCardService.deleteByIdList(ids);
        return ResultUtil.success();
    }

    /**
     * 根据id删除卡券
     */
    @RequestMapping(value = "/deleteById", method = RequestMethod.POST)
    @ApiOperation("删除卡券")
    public Result deleteById(@RequestParam Long id) {
        RequestLogs requestLogs = new RequestLogs();
        requestLogs.saveRequestLogs(new java.util.Date(),new java.util.Date(),
                "deleteById",null,
                "/couponCard/deleteById", String.valueOf(id));

        requestLogsService.saveRequestLogs(requestLogs);
        couponCardService.deleteById(id);
        return ResultUtil.success();
    }

}
